package com.hcj.springcloud.ChainOfResponsibilityPattern;

import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;

/**
 * 责任链-demo
 * 常见框架中的日志、过滤器、拦截器都是责任链
 *
 * @author huangchangjin
 * @date 2023/11/28 10:11
 */
@Slf4j
public class Demo {

    abstract static class AbstractLogger {
        public static final int INFO = 1;
        public static final int DEBUG = 2;
        public static final int ERROR = 3;

        protected Integer level;
        protected AbstractLogger nextLogger;

        // 需要子类实现
        protected abstract void write(String msg);

        public void logMessage(int level, String msg) {
            if (level <= this.level) {
                write(msg);
            }

            if (nextLogger != null) {
                nextLogger.logMessage(level, msg);
            }
        }

        public void setNextLogger(AbstractLogger nextLogger) {
            this.nextLogger = nextLogger;
        }
    }

    static class InfoLogger extends AbstractLogger {
        public InfoLogger(Integer level) {
            this.level = level;
        }

        @Override
        protected void write(String msg) {
            log.info("InfoLogger level = {}, msg = {}", level, msg);
        }
    }

    static class ErrorLogger extends AbstractLogger {
        public ErrorLogger(Integer level) {
            this.level = level;
        }

        @Override
        protected void write(String msg) {
            log.error("ErrorLogger level = {}, msg = {}", level, msg);
        }
    }

    static class DebugLogger extends AbstractLogger {
        public DebugLogger(Integer level) {
            this.level = level;
        }

        @Override
        protected void write(String msg) {
            log.info("DebugLogger level = {}, msg = {}", level, msg);
        }
    }

    /**
     * 自定义日志配置
     */
    static final class MyLogConfig {
        /**
         * 构建日志链
         */
        static AbstractLogger buildChainLogger() {
            // 打印日志的优先级：error >= debug >= info
            AbstractLogger error = new ErrorLogger(AbstractLogger.ERROR);
            AbstractLogger debug = new DebugLogger(AbstractLogger.DEBUG);
            AbstractLogger info = new InfoLogger(AbstractLogger.INFO);

            error.setNextLogger(debug);
            debug.setNextLogger(info);

            return error;
        }

    }

    @Test
    void test_main() {
        AbstractLogger logger = MyLogConfig.buildChainLogger();
        // 输出3个等级的日志(error, debug, info)
        logger.logMessage(AbstractLogger.INFO, "msg info");

        // 输出2个等级的日志(error, debug)
        logger.logMessage(AbstractLogger.DEBUG, "msg debug");

        // 只输出1个等级日志(error)
        logger.logMessage(AbstractLogger.ERROR, "msg error");

    }
}
